package org.wxd.bi.controller;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wxd.batis.query.SortEnum;
import org.wxd.batis.sql.SqlQueryBuilder;
import org.wxd.batis.sql.mysql.MysqlFactory;
import org.wxd.bi.api.PushApi;
import org.wxd.bi.api.struct.PushColumn;
import org.wxd.bi.api.struct.PushMapping;
import org.wxd.bi.data.AppFactory;
import org.wxd.bi.data.AppService;
import org.wxd.bi.po.AppInfo;
import org.wxd.bi.po.UserInfo;
import org.wxd.lang.RunResult;
import org.wxd.net.controller.ann.TextController;
import org.wxd.net.controller.ann.TextMapping;
import org.wxd.net.controller.cmd.RunCode;
import org.wxd.net.web.hs.HttpSession;
import org.wxd.net.web.hs.controller.cmd.HttpSign;
import org.wxd.net.web.hs.controller.cmd.HttpSignCheck;
import org.wxd.str.StringUtil;
import org.wxd.str.json.JsonUtil;
import org.wxd.str.json.Object2Json;
import org.wxd.timer.TimeUtil;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 应用管理
 *
 * @author: Troy.Chen(無心道, 15388152619)
 * @version: 2021-10-21 15:36
 **/
@TextController(url = "appinfo")
public class AppController implements Serializable, BaseQuery, HttpSign, HttpSignCheck, RunCode {

    private static final long serialVersionUID = 1L;
    private static final Logger log = LoggerFactory.getLogger(AppController.class);

    @Resource
    private AppFactory appFactory;
    @Resource
    private MysqlFactory mysqlFactory;

    @Override
    public String token(String username, String md5Pwd, String ip) throws Exception {
        UserInfo user = appFactory.queryUserInfo(username);
        if (user != null && md5Pwd.equals(user.getUserPwd())) {
            return cacheToken(username, ip);
        }
        return null;
    }

    @TextMapping(remarks = "查询所有应用")
    public RunResult queryAll(JSONObject params, HttpSession session) throws Exception {
        final UserInfo user = appFactory.queryUserInfo(session);

        final Map<Integer, AppService> dataServiceMap = appFactory.getDataServiceMap();
        List<String[]> list = new ArrayList<>();
        for (AppService appService : dataServiceMap.values()) {
            AppInfo appInfo = appService.getAppInfo();
            list.add(new String[]{String.valueOf(appInfo.getAppId()), appInfo.getAppName(), appInfo.getComment()});
        }
        return RunResult.ok().setData(list);
    }

    @TextMapping(remarks = "映射结构体")
    public RunResult addAppInfo(JSONObject params, HttpSession session) throws Exception {
        final UserInfo user = appFactory.queryUserInfo(session);

        final int appId = params.getIntValue("appId");
        final String appName = params.getString("appName");
        final String comment = params.getString("comment");
        AppInfo appInfo = appFactory.queryAppInfo(appId);
        if (appInfo == null) {
            appInfo = new AppInfo()
                    .setAppId(appFactory.newAppId())
                    .setAppToken(StringUtil.getRandomString(32))
                    .setCreateTime(TimeUtil.currentTimeMillis());
        }
        appInfo.setAppName(appName)
                .setComment(comment);
        mysqlFactory.dataHelper().replace(appInfo);
        appFactory.dataService(appInfo.getAppId());

        return RunResult.ok();
    }


    @TextMapping(remarks = "映射结构体")
    public RunResult title(JSONObject params, HttpSession session) throws Exception {
        final UserInfo userInfo = appFactory.queryUserInfo(session);

        final PushMapping appInfoMapping = PushApi.buildPushMapping(AppInfo.class);
        long count = mysqlFactory.dataHelper().getCount(appInfoMapping.getTableName(), null);
        int pageSize = params.getIntValue("pageSize");
        long pageMax = count / pageSize + (count % pageSize > 0 ? 1 : 0);

        RunResult ok = RunResult.ok()
                .putData("columnInfo", appInfoMapping.htmlColumnInfo())
                .putData("dataCount", String.valueOf(count))
                .putData("pageMax", pageMax);
        return ok;
    }

    @TextMapping(remarks = "查询数据")
    public RunResult data(JSONObject params, HttpSession session) throws Exception {
        final UserInfo userInfo = appFactory.queryUserInfo(session);

        final PushMapping appInfoMapping = PushApi.buildPushMapping(AppInfo.class);
        int pageIndex = params.getIntValue("pageIndex");
        int pageSize = params.getIntValue("pageSize");

        List<String> datas = new LinkedList<>();

        SqlQueryBuilder sqlQueryBuilder = builderWhere(params.getString("queryWhere"));
        sqlQueryBuilder.from(appInfoMapping.getTableName());

        if (appInfoMapping.mapping().getColumnMap().containsKey(PushColumn.SAVE_TIME.getName())) {
            sqlQueryBuilder.sort(PushColumn.SAVE_TIME.getName(), SortEnum.Max_Min);
        }
        if (appInfoMapping.mapping().getColumnMap().containsKey(PushColumn.ID.getName())) {
            sqlQueryBuilder.sort(PushColumn.ID.getName(), SortEnum.Max_Min);
        }

        mysqlFactory.dataHelper().query(sqlQueryBuilder, (data) -> {
            Long saveTime = data.getLong(PushColumn.SAVE_TIME.getName());
            if (saveTime != null) {
                try {
                    data.put(PushColumn.SAVE_TIME.getName(), TimeUtil.formatDateString("yyyy-MM-dd HH:mm:ss:SSS", saveTime));
                } catch (Exception e) {
                }
            }
            Long createTime = data.getLong(PushColumn.CREATE_TIME.getName());
            if (createTime != null) {
                try {
                    data.put(PushColumn.CREATE_TIME.getName(), TimeUtil.formatDateString("yyyy-MM-dd HH:mm:ss:SSS", createTime));
                } catch (Exception e) {
                }
            }
            datas.add(Object2Json.toJson(data, JsonUtil.FeaturesAllString));
        });
        return RunResult.ok().putData("rows", datas);
    }

}
